#include "face_loginwindow.h"
#include "ui_face_loginwindow.h"
#include <QImage>
#include <QDebug>
#include <QMessageBox>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>

Face_LoginWindow::Face_LoginWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Face_LoginWindow)
{
    ui->setupUi(this);
    cap.open(0);        //打开摄像头

    //启动定时器事件
    startTimer(100);

    //导入级联分裂器文件
    cascade.load("C:/Qt+opencv/opencv452/etc/haarcascades/haarcascade_frontalface_alt2.xml");

    //QTcpSocket当断开连接的时候disconnected信号，连接成功就会发送connected
    connect(&msocket,&QTcpSocket::disconnected,this,&Face_LoginWindow::start_connect);
    connect(&msocket,&QTcpSocket::connected,this,&Face_LoginWindow::stop_connect);

    //关联接收数据的槽函数
    connect(&msocket,&QTcpSocket::readyRead,this,&Face_LoginWindow::recv_data);
    //定时器连接服务器
    connect(&mtimer,&QTimer::timeout,this,&Face_LoginWindow::timer_connect);
    //启动定时器
    mtimer.start(5000); //每5s钟连接一次，直到连接成功就不在连接
    flag = 0;

    ui->label_img->hide();
}

Face_LoginWindow::~Face_LoginWindow()
{
    delete ui;
}

void Face_LoginWindow::timerEvent(QTimerEvent *e)
{
    Q_UNUSED(e)
    //采集数据
    Mat srcImage;
    if(cap.grab())
    {
        cap.read(srcImage); //读取一帧数据
    }

    //创建灰度图
    Mat grayImage;
    cvtColor(srcImage,grayImage,COLOR_BGR2GRAY);

    //检测人脸数据
    std::vector<Rect> faceRects;
    //使用灰度图进行人脸检测
    cascade.detectMultiScale(grayImage,faceRects);
    if(faceRects.size() > 0)
    {
        Rect rect = faceRects.at(0);        //第一个人脸的矩形框
        //移动人脸框
        ui->label_faceShow->move(rect.x,rect.y);

        if(flag > 2)
        {
            //把Mat数据转换为QByteArray，--》编码成jpg格式
            std::vector<uchar> buf;
            cv::imencode(".jpg",srcImage,buf);
            QByteArray byte((const char*)buf.data(),buf.size());
            //准备发送
            quint64 backsize = byte.size();
            QByteArray sendData;
            QDataStream stream(&sendData,QIODevice::WriteOnly);
            stream.setVersion(QDataStream::Qt_5_14);
            stream<<backsize<<byte;
            //发送
            msocket.write(sendData);
            flag = -2;
            faceMat = srcImage(rect);

            //保存
            imwrite("./face.jpg",faceMat);
        }
        flag++;
    }
    if(faceRects.size() == 0)
    {
        //把人脸框移动到中心位置
        ui->label_faceShow->move(100,60);
        flag = 0;
        ui->label_img->hide();
        ui->label_success->setText("识别中");
        ui->label_success->setStyleSheet("background-color:white");
        ui->headLb->clear();
    }

    if(srcImage.data == nullptr) return;    //如果数据为空，则返回

    //把opencv里面的Mat格式数据转QImage
    cvtColor(srcImage,srcImage,COLOR_BGR2RGB);
    //创建Qt的QImage对象，提取Mat矩阵的图像数据
    QImage image(srcImage.data,srcImage.cols,srcImage.rows,srcImage.step1(),QImage::Format_RGB888);
    //将QImage对象转换为QPixmap对象
    QPixmap mmp = QPixmap::fromImage(image);
    //将图片显示到标签
    ui->label_background->setPixmap(mmp);
}

void Face_LoginWindow::timer_connect()
{
    //连接服务器
    msocket.connectToHost("192.168.70.28",8080);
    qDebug()<<"正在连接服务器";
}

void Face_LoginWindow::stop_connect()
{
    mtimer.stop();
    qDebug()<<"成功连接服务器";
    QMessageBox::information(this,"提示","服务器连接成功");
}

void Face_LoginWindow::start_connect()
{
    mtimer.start(5000); //启动定时器
    qDebug()<<"服务器断开连接";
}

void Face_LoginWindow::recv_data()
{
    QByteArray array = msocket.readAll();
    qDebug()<<array;
    //Json解析
    QJsonParseError err;
    QJsonDocument doc = QJsonDocument::fromJson(array,&err);
    if(err.error != QJsonParseError::NoError)
    {
        qDebug()<<"json数据错误";
        return;
    }

    QJsonObject obj = doc.object();
    QString employeeID = obj.value("employeeID").toString();
    QString name = obj.value("name").toString();
    QString department = obj.value("department").toString();
    QString timestr = obj.value("time").toString();

    ui->lineEdit_num->setText(employeeID);
    ui->lineEdit_name->setText(name);
    ui->lineEdit_department->setText(department);
    ui->lineEdit_time->setText(timestr);

    //通过样式来显示图片
    ui->headLb->setStyleSheet("border-radius:75px;border-image:url(./face.jpg)");
    ui->label_img->show();
    ui->label_success->setText("识别成功");
    ui->label_success->setStyleSheet("background-color:red");
}
